`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////Asyncsys Lab////////////////////////////////////////
// Author: Zhenbang Kang
// Email: kangzhb20@lzu.edu.cn
// Create Date: 2022/06/10 
// Module Name: rst_filter
// Project Name: ac8051 (Asynchronous Click 8051)
// Target Devices: XC7A100TFGG484-2
// Tool Versions: Vivado 2019.1
// Description:Asynchronous Reset Module
// Revision: V2.0
//////////////////////////////////////////////////////////////////////////////////

module rst_filter(
        clk,
        rst_n,
        rst_n_out
    );
    
    input   clk;
    input   rst_n;
    output  rst_n_out;
    
    wire    clk;
    wire    rst_n;
    wire    rst_n_out;
    wire    i_rst_keep;
    
    reg     [6:0] rst_cnt_1;
    reg     [6:0] rst_cnt_2;
    reg           rst_begin;
    reg           rst_end;
    reg           rst_final;
    
    reg     [6:0] rst_cnt_3;
    reg     [6:0] rst_cnt_4;
    reg           rst_begin2;
    reg           rst_end2;
    reg           rst_keep;
/*************************first_filter*************************/    
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            rst_cnt_1 <= 'b0;
        end else if(rst_begin==0)begin
            rst_cnt_1 <= rst_cnt_1;
        end else begin
            rst_cnt_1 <= rst_cnt_1 + 1;
        end
    end
    
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            rst_begin <= 'b1;
        end else if(rst_cnt_1==7'd100)begin
            rst_begin <= 'b0;
        end else begin
            rst_begin <= rst_begin;
        end
    end
    
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            rst_cnt_2 <= 'b0;
        end else if ((rst_begin==1'b0)&&(rst_end==1'b0))begin
            rst_cnt_2 <= rst_cnt_2 + 1;
        end else begin
            rst_cnt_2 <= rst_cnt_2;
        end
    end
    
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            rst_end <= 'b0;
        end else if(rst_cnt_2==7'd100)begin
            rst_end <= 'b1;
        end else begin
            rst_end <= rst_end;
        end
    end

    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            rst_keep <= 'b1;
        end else if((rst_begin==1'b0)&&(rst_end==1'b0))begin
            rst_keep <= 'b0;
        end else begin
            rst_keep <= 'b1;
        end
    end
    assign i_rst_keep=rst_keep;
/*************************second_filter*************************/ 
    always@(posedge clk or negedge rst_keep)begin
        if(!rst_keep)begin
            rst_cnt_3 <= 'b0;
        end else if(rst_begin2==0)begin
            rst_cnt_3 <= rst_cnt_3;
        end else if(rst_end==1)begin
            rst_cnt_3 <= rst_cnt_3 + 1;
        end else begin
            rst_cnt_3 <= rst_cnt_3;
        end
    end
    
    always@(posedge clk or negedge rst_keep)begin
        if(!rst_keep)begin
            rst_begin2 <= 'b1;
        end else if(rst_cnt_3==7'd100)begin
            rst_begin2 <= 'b0;
        end else begin
            rst_begin2 <= rst_begin2;
        end
    end
    
    always@(posedge clk or negedge rst_keep)begin
        if(!rst_keep)begin
            rst_cnt_4 <= 'b0;
        end else if ((rst_begin2==1'b0)&&(rst_end2==1'b0))begin
            rst_cnt_4 <= rst_cnt_4 + 1;
        end else begin
            rst_cnt_4 <= rst_cnt_4;
        end
    end
    
    always@(posedge clk or negedge rst_keep)begin
        if(!rst_keep)begin
            rst_end2 <= 'b0;
        end else if(rst_cnt_4==7'd100)begin
            rst_end2 <= 'b1;
        end else begin
            rst_end2 <= rst_end2;
        end
    end
    
    always@(posedge clk or negedge rst_keep)begin
        if(!rst_keep)begin
            rst_final <= 'b1;
        end else if((rst_begin2==1'b0)&&(rst_end2==1'b0))begin
            rst_final <= 'b0;
        end else begin
            rst_final <= 'b1;
        end
    end
    assign i_rst_keep=rst_keep;    
    assign rst_n_out = rst_final;    
endmodule
